﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using PJ.Data.WCF;
using PJ.Framework;

namespace PJ.Data
{
    public class ItemWCFProxyProvider<C, S, D, I> : EntityWCFProxyProvider<C, S, D, I>, IItemProvider<I>
        where I : class, IItemData
        where D : BaseItemData, I, new()
        where S : class, IItemWCFProvider<D>
        where C : ItemProviderClient<S, D>, new()
    {
        public ItemWCFProxyProvider(IItemCache<I> cache)
            : base(cache)
        {
        }

        public I GetByName(string name, GetDataMode mode)
        {
            if (name == null || name == "")
                throw new ArgumentNullException();
            I entity = null;
            if (Cache != null && (mode & GetDataMode.UseCache) == GetDataMode.UseCache)
                entity = Cache.FindByName(name);
            if (entity == null)
            {
                try
                {
                    entity = ClientBase.GetByName("", name, (int)mode) as I;
                    if (entity != null && Cache != null)
                        Cache.Add(entity);
                }
                catch (Exception ex)
                {
                    ClientBase = null;
                    ExceptionManager.Handle(ex);
                    throw;
                }
            }
            else
                return entity;
            if (entity == null && (mode & GetDataMode.Find) != GetDataMode.Find)
                throw new DataNotFoundException("name", name);
            return entity;
        }

        public I GetByAlias(string aliasName, GetDataMode mode)
        {
            if (aliasName == null || aliasName == "")
                throw new ArgumentNullException();
            I entity = null;
            if (Cache != null && (mode & GetDataMode.UseCache) == GetDataMode.UseCache)
                entity = Cache.FindByAlias(aliasName);
            if (entity == null)
            {
                try
                {
                    entity = ClientBase.GetByAlias("", aliasName, (int)mode) as I;
                    if (entity != null && Cache != null)
                        Cache.Add(entity);
                }
                catch (Exception ex)
                {
                    ClientBase = null;
                    ExceptionManager.Handle(ex);
                    throw;
                }
            }
            else
                return entity;
            if (entity == null && (mode & GetDataMode.Find) != GetDataMode.Find)
                throw new DataNotFoundException("aliasName", aliasName);
            return entity;
        }


        public string[] Search(string searchText, GetDataMode mode)
        {
            if (searchText == null || searchText == "")
                throw new ArgumentNullException();
            string[] searchResult = null;
            if (Cache != null && (mode & GetDataMode.UseCache) == GetDataMode.UseCache)
                searchResult = Cache.Search(searchText);
            if (searchResult == null)
            {
                try
                {
                    searchResult = ClientBase.Search("", searchText, (int)mode);
                    if (Cache != null && searchResult != null)
                        Cache.AddSearch(searchText, searchResult);
                }
                catch (Exception ex)
                {
                    ClientBase = null;
                    ExceptionManager.Handle(ex);
                    throw ex;
                }
            }
            else
                return searchResult;
            if (searchResult == null && (mode & GetDataMode.Find) != GetDataMode.Find)
                throw new DataNotFoundException("searchText", searchText);
            return searchResult;
        }
        #region Interface override

        IItemData IItemProvider.GetByName(string name, GetDataMode mode)
        {
            return GetByName(name, mode);
        }

        IItemData IItemProvider.GetByAlias(string aliasName, GetDataMode mode)
        {
            return GetByAlias(aliasName, mode);
        }

        #endregion

        #region Protected

        new protected IItemCache<I> Cache
        {
            get { return (IItemCache<I>)base.Cache; }
        }

        #endregion

    }
}
